import { Injectable, UnauthorizedException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { User } from 'src/entities/user.entity';
import { CryptoUtil } from 'src/common/utils/crypto.util';
import { TimeUtil } from 'src/common/utils/time.util';
// 此错误通常表示未安装 @nestjs/jwt 包，需要先运行以下命令安装：
// npm install @nestjs/jwt @types/jsonwebtoken jsonwebtoken
import { JwtService } from '@nestjs/jwt';
import { CreateUserDTO } from 'src/dto/user/create-user.dto';
import { UpdateUserDTO } from 'src/dto/user/update-user.dto';
// - 实现用户业务逻辑：
// - 用户登录验证和token生成
// - 用户CRUD操作
// - 密码加密
// - 初始化时创建默认管理员账户
@Injectable()
export class UserService {
  constructor(
    @InjectRepository(User)
    private readonly userRepository: Repository<User>,
    private readonly cryptoUtil: CryptoUtil,
    private readonly jwtService: JwtService,
  ) {}

  async onModuleInit() {
    console.log('UserModule init');
    if (await this.findOneByAccount('admin')) {
      console.log('Admin account already exists');
      return;
    }
    const admin = this.userRepository.create({
      account: 'admin',
      password: this.cryptoUtil.encryptPassword('admin') as string,
      name: 'Admin User',
      role: 'admin',
    });
    await this.userRepository.save(admin);
  }

  /**
   * 用户登录
   * @param account 账户名
   * @param password 密码
   * @returns 用户信息和token
   */
  async login(
    account: string,
    password: string,
  ): Promise<{
    user: Omit<User, 'password'>;
    token: string;
  }> {
    const user = await this.userRepository.findOne({
      where: { account },
    });

    if (!user) {
      throw new UnauthorizedException('账户不存在');
    }

    const isPasswordValid = this.cryptoUtil.verifyPassword(
      password,
      user.password,
    );

    if (!isPasswordValid) {
      throw new UnauthorizedException('密码错误');
    }

    // 生成token
    const token = this.jwtService.sign({
      id: user.id,
      account: user.account,
      role: user.role,
    });

    // 删除密码字段
    const { password: _, ...userWithoutPassword } = user;

    return {
      user: userWithoutPassword,
      token,
    };
  }

  /**
   * 创建用户
   * @param createUserDTO 用户创建数据
   * @returns 创建的用户
   */
  async create(createUserDTO: CreateUserDTO): Promise<User> {
    // 检查账户是否已存在
    const existingUser = await this.userRepository.findOne({
      where: { account: createUserDTO.account },
    });

    if (existingUser) {
      throw new Error('账户已存在');
    }

    // 加密密码
    const encryptedPassword = this.cryptoUtil.encryptPassword(
      createUserDTO.password,
    ) as string;

    // 创建用户
    const user = this.userRepository.create({
      ...createUserDTO,
      password: encryptedPassword,
    });

    return this.userRepository.save(user);
  }

  /**
   * 获取用户列表
   * @returns 用户列表
   */
  async findAll(): Promise<User[]> {
    // 从数据库中查询所有用户
    // 注意：在实际应用中，为了避免返回敏感信息（如密码），
    // 过滤密码字段的返回
    const users = await this.userRepository.find({
      select: {
        id: true,
        account: true,
        name: true,
        role: true,
        email: true,
        phone: true,
        createdAt: true,
        updatedAt: true,
      },
    });

    // 格式化时间字段
    return TimeUtil.formatUserListTimeFields(users);
  }

  /**
   * 根据账户名获取用户
   * @param account 账户名
   * @returns 用户信息
   */
  async findOneByAccount(account: string): Promise<User | null> {
    return this.userRepository.findOne({
      where: { account },
    });
  }

  /**
   * 根据ID获取用户
   * @param id 用户ID
   * @returns 用户信息
   */
  async findOneById(id: number): Promise<User | null> {
    // 根据ID查询用户，同时过滤密码字段
    const user = await this.userRepository.findOne({
      where: { id },
      select: {
        id: true,
        account: true,
        name: true,
        role: true,
        email: true,
        phone: true,
        createdAt: true,
        updatedAt: true,
      },
    });

    // 格式化时间字段
    return user ? TimeUtil.formatUserTimeFields(user) : null;
  }

  /**
   * 更新用户
   * @param id 用户ID
   * @param updateUserDTO 用户更新数据
   * @returns 更新后的用户
   */
  async update(id: number, updateUserDTO: UpdateUserDTO): Promise<User> {
    const user = await this.userRepository.findOne({
      where: { id },
    });

    if (!user) {
      throw new Error('用户不存在');
    }

    // 如果更新密码，则加密
    if (updateUserDTO.password) {
      updateUserDTO.password = this.cryptoUtil.encryptPassword(
        updateUserDTO.password,
      ) as string;
    }

    // 更新用户信息
    Object.assign(user, updateUserDTO);

    return this.userRepository.save(user);
  }

  /**
   * 删除用户
   * @param id 用户ID
   * @returns 删除结果
   */
  async remove(id: number): Promise<{
    success: boolean;
    message: string;
  }> {
    const user = await this.userRepository.findOne({
      where: { id },
    });

    if (!user) {
      return {
        success: false,
        message: '用户不存在',
      };
    }

    await this.userRepository.delete(id);

    return {
      success: true,
      message: '用户删除成功',
    };
  }
  // async findOne(account: string): Promise<User | undefined> {
  //   console.log('user service ts findone enter', account);
  //   const user = await this.userRepository.findOne({
  //     where: {
  //       account,
  //     },
  //   });
  //   console.log('user service ts findone leave', user);
  //   return user === null ? undefined : user;
  // }
}


